from abc import ABC, abstractmethod
from typing import AnyStr, List

from .job import Job


class JobLookupError(KeyError):
    def __init__(self, job_id):
        super(JobLookupError, self).__init__('任务({})不存在'.format(job_id))


class ConflictingIdError(KeyError):
    def __init__(self, job_id):
        super(ConflictingIdError, self).__init__('任务({})已经存在'.format(job_id))


class BaseJobStore(ABC):
    @abstractmethod
    def add_job(self, job: Job) -> None:
        '''
        :raises ConflictingIdError: 任务已经存在抛异常
        '''

    @abstractmethod
    def lookup_job(self, job_id: str) -> Job:
        '''
        :raises JobLookupError: 任务不存在抛异常
        '''

    @abstractmethod
    def update_job(self, job: Job) -> None:
        '''
        :raises JobLookupError: 任务不存在抛异常
        '''

    @abstractmethod
    def remove_job(self, job: Job) -> None:
        pass

    @abstractmethod
    def get_due_jobs(self, now: int, count: int, local_job_ids: List[AnyStr] = []) -> List[Job]:
        '''
        :param int now: 时间戳
        :param int count: 获取任务数量
        '''

    @abstractmethod
    def get_next_run_time(self):
        '''
        :return int or None: 确保返回整数
        '''

    @abstractmethod
    def lock_jobs(self, jobs: List[Job], lock_expire_time: int):
        pass

    def remove_all_jobs(self):
        pass
